package cn.itsource.order.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.CodeGenerateUtils;
import cn.itsource.basic.util.PageList;
import cn.itsource.order.domain.AdoptOrder;
import cn.itsource.order.domain.OrderAddress;
import cn.itsource.order.mapper.AdoptOrderMapper;
import cn.itsource.order.mapper.OrderAddressMapper;
import cn.itsource.order.query.AdoptOrderQuery;
import cn.itsource.order.service.IAdoptOrderService;
import cn.itsource.org.domain.Employee;
import cn.itsource.org.mapper.EmployeeMapper;
import cn.itsource.pay.constants.OrderConstants;
import cn.itsource.pay.domain.PayBill;
import cn.itsource.pay.mapper.PayBillMapper;
import cn.itsource.pay.service.IPayBillService;
import cn.itsource.pet.domain.Pet;
import cn.itsource.pet.mapper.PetMapper;
import cn.itsource.quartz.constants.QuartzConstants;
import cn.itsource.quartz.service.IQuartzService;
import cn.itsource.quartz.utils.QuartzJobInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.UserAddress;
import cn.itsource.user.mapper.UserAddressMapper;
import cn.itsource.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends BaseServiceImpl<AdoptOrder> implements IAdoptOrderService {
    @Autowired
    private PetMapper petMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AdoptOrderMapper adoptOrderMapper;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private PayBillMapper payBillMapper;
    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private IQuartzService quartzService;

    /**
     * 用户提交订单 接收数据
         params{
             service_method:'0',
             address_id: '1',
             pay_method:'2',
             pet_id:null,
         }
         用户id
     * @param params
     * @param id
     */
    @Override
    public String submit(Map<String, Object> params, Long id) {
        // 宠物id
        Long petId = Long.valueOf(params.get("pet_id").toString());
        // 地址id
        Long addressId = Long.valueOf(params.get("address_id").toString());
        // 邮寄方式
        Integer serviceMethod = Integer.valueOf(params.get("service_method").toString());
        // 支付方式
        Long payMethod = Long.valueOf(params.get("pay_method").toString());
            // 1.下架宠物
            /*Map<String,Object> offsale = new HashMap<>();
            offsale.put("offsaleTime",new Date());
            offsale.put("id",petId);
            petMapper.offSale(offsale);*/
        // 查询宠物信息
        Pet pet = petMapper.loadById(petId);
        // 2.绑定用户
        User user = userMapper.loadByLoginInfoId(id);// 查询用户
        if (user != null){
            pet.setUser_id(user.getId()); // 绑定用户
            pet.setOffsaletime(new Date()); // 下架时间
            pet.setState(0); // 修改状态
            // 调用方法完成宠物信息修改 （绑定用户，修改下架时间，修改下架状态）
            petMapper.update(pet);
        }


        // 3.生成订单
        AdoptOrder adoptOrder = initAdoptOrder(petId, pet, user);
        String unionPaySn = CodeGenerateUtils.generateUnionPaySn();
        adoptOrder.setPaySn(unionPaySn);
        adoptOrderMapper.save(adoptOrder);
        // 4.订单地址
        // 查询用户地址
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        // 将用户地址复制到订单地址
        OrderAddress orderAddress = initOrderAddress(adoptOrder, userAddress);
        // 保存订单地址
        orderAddressMapper.save(orderAddress);

        //5. 支付
        //5.1 生成支付单
        PayBill bill = initPayBill(payMethod, pet, user, adoptOrder);
        payBillMapper.save(bill);
        System.out.println(bill+"打印支付单");

        //5.2 调用【统一的支付接口 】
        //5.3 返回同步信息给前端 （扫码界面）
        //6. @TODO 订单定时取消
        QuartzJobInfo info = new QuartzJobInfo();
        info.setType(QuartzConstants.ORDER_ADOPT_TYPE_CANCEL);
        String jobName = QuartzConstants.ORDER_ADOPT_CANCEL_PREFIX + adoptOrder.getPaySn();
        info.setJobName(jobName);
        Map<String, Object> paramsQuartz = new HashMap<>();
        paramsQuartz.put("orderId", adoptOrder.getId());
        info.setParams(paramsQuartz);
        info.setFireDate(adoptOrder.getLastPayTime());
        //添加超时未支付取消定时任务
        quartzService.addJob(info);
        System.out.println(adoptOrder.getDigest()+"已添加定时任务");
        return payBillService.pay(bill);
    }

    private PayBill initPayBill(Long payMethod, Pet pet, User user, AdoptOrder order) {
        PayBill bill = new PayBill();
        bill.setDigest(order.getDigest());
        bill.setMoney(order.getPrice());
        bill.setUnionPaySn(order.getPaySn());
        bill.setLastPayTime(new Date(System.currentTimeMillis() + OrderConstants.ORDER_TIMEOUT));
        bill.setPayChannel(payMethod);
        bill.setBusinessType(OrderConstants.BUSINESS_TYPE_ADOPT_ORDER);
        bill.setBusinessKey(order.getId());
        bill.setUser_id(user.getId());
        bill.setNickName(user.getUsername());
        bill.setShop_id(pet.getShop_id());
        return bill;
    }

    private OrderAddress initOrderAddress(AdoptOrder adoptOrder, UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        orderAddress.setId(null);//拷贝的时候直接将id页拷贝过来了，所以要指控
        orderAddress.setOrder_id(adoptOrder.getId());
        orderAddress.setOrderSn(adoptOrder.getOrderSn());
        return orderAddress;
    }


    // 生成订单
    private AdoptOrder initAdoptOrder(Long petId, Pet pet, User user) {
        /*
        生成订单包含：digest 名称
                price 售价
                orderSn 订单编号
                paySn 支付订单号
                lastPayTime
                lastConfirmTime 订单关闭时间 15分钟
                pet_id 宠物id
                user_id 用户id
                shop_id 店铺id
                address_id
          */
        AdoptOrder adoptOrder = new AdoptOrder();
        adoptOrder.setDigest("[领养]"+pet.getName()+"的订单");
        adoptOrder.setPrice(pet.getSaleprice());
        adoptOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        adoptOrder.setLastConfirmTime(new Date(System.currentTimeMillis() + 15*60*1000));
        adoptOrder.setPet_id(petId);
        adoptOrder.setUser_id(user.getId());
        adoptOrder.setShop_id(pet.getShop_id());
        return adoptOrder;
    }

    // 管理员查询订单
    @Override
    public PageList<AdoptOrder> admin(AdoptOrderQuery query, Long loginInfoId) {
        // 根据登录id拿到管理员信息，判断平台/店铺管理员，根据店铺id查询订单
        Employee employee = employeeMapper.loadByLoginInfoId(loginInfoId);
        if(employee.getShop_id() != null){
            query.setShop_id(employee.getShop_id());
        }
        return super.queryForPage(query);
    }

    // 用户查询订单
    @Override
    public PageList<AdoptOrder> user(AdoptOrderQuery query, Long id) {
        // 根据登录id查询用户拿到用户id，然后根据用户id查询订单返回
        User user = userMapper.loadByLoginInfoId(id);
        if(user != null){
            query.setUser_id(user.getId());
        }
        return super.queryForPage(query);
    }

    @Override
    public void quartzCancel(Long orderId) {
        //修改领养订单状态
        AdoptOrder order = adoptOrderMapper.loadById(orderId);
        order.setState(-1);
        adoptOrderMapper.update(order);
        //修改支付单状态
        String unionPaySn = order.getPaySn();
        PayBill bill = payBillMapper.loadByUnionPaySn(unionPaySn);
        bill.setState(-1);
        payBillMapper.update(bill);
        System.out.println(order.getDigest()+":订单被Quartz取消了！");
    }
}
